ci: answer "is a boringssl bump safe" by test, not by argument - #178
Conversation
Merging a boringssl snapshot bump (e.g. Renovate's #177) today rests partly on reading upstream commit logs. Convert each remaining argument into a red-or-green check: - Pin the TLS ceiling, not just the floor: an uncapped handshake must land on TLS 1.3 (server-side probe), and the client must reach a 1.3-only listener (CappedTlsServer grows an optional floor). A boringssl default drifting would now fail beast_client_test instead of passing every floor test. - Resolution invariant in the consumer job: the consumer's resolved boringssl must equal the MODULE.bazel pin, so MVS silently selecting a higher version a transitive dep requested becomes a failure (boringssl-resolution-check.sh). - Lockfile freshness leg: bazelisk mod deps --lockfile_mode=error for the root and consumer modules, so a MODULE.bazel edit lands with its lockfile and dependency PRs stay auditable from the diff. The leg earned its keep immediately: the consumer lockfile was already stale (rules_shell 0.8.0 was added without a repin) — regenerated here. - Canary workflow: twice a week, force the newest BCR boringssl onto both module graphs via single_version_override and run the TLS- pinning runtime suites plus the consumer acceptance tests — failing *before* the next Renovate bump opens, and standing in for the consumer whose other deps drag boringssl past our pin. - Renovate: osvVulnerabilityAlerts for the advisory direction ("is it safe NOT to merge"), and a repin note on every bazel-module PR mirroring the maven_install.json posture. make lockfiles joins verify; the consumer target runs the resolution check; docs list the new target. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015oE5zkytVkgzmKNPSP2CWM
ReviewVerdict: approve with a few small follow-ups. The PR does what it claims — turns “is this boringssl bump safe?” into red/green checks — and CI is fully green (including the new What works well
Findings
Optional / non-blocking
Not concerns
Bottom line: merge-ready after considering the canary |
Review follow-ups (PR #178): the canary's single_version_override makes the checked-in lockfiles stale by construction, so its test steps now pass --lockfile_mode=off explicitly instead of relying on Bazel's current default of update — a future default of error would have failed the run before any test executed. docs/development.md's verify summary and underlying-commands block now mention lockfile freshness alongside the other gates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015oE5zkytVkgzmKNPSP2CWM
|
Addressed the three findings in 63b1b14:
The optional items (canary failure issue/notification, multi-line Generated by Claude Code |
What
Assessing a boringssl snapshot bump (e.g. Renovate's #177) today still rests partly on argument — reading upstream commit logs, reasoning about MVS. This PR converts each of those remaining arguments into a red-or-green check:
runtime/tests/http/beast_client_test.cc): the suite pinned the 1.2 floor, AEAD ciphers, and ALPN, but not the ceiling actually reached. Two new tests assert an uncapped handshake lands on TLS 1.3 (server-side raw probe) and that the client reaches a TLS-1.3-only listener (CappedTlsServergrows an optional floor). A boringssl bump that quietly moved the default protocol version now fails a test instead of passing every floor check. Session resumption is deliberately not pinned: neither transport configures it, so there is no behavior to pin.examples/bazel-consumer/boringssl-resolution-check.sh, wired into the consumer job): the consumer's resolved boringssl must equal theMODULE.bazelpin. Bazel's MVS picks the highest version any module requests, so a transitive dep could drag the TLS library past the pinned-and-tested version with every leg still green; that skew is now a failure.lockfilesjob):bazelisk mod deps --lockfile_mode=errorfor the root and consumer modules, so aMODULE.bazeledit lands together with its lockfile and dependency PRs stay auditable from the diff — same posture as the codegen job's golden-freshness check. The leg earned its keep immediately: the checked-in consumer lockfile was already stale (rules_shell0.8.0 was added without a repin); regenerated here..github/workflows/canary.yml): twice a week (and on demand), force the newest BCR boringssl onto both module graphs viasingle_version_overrideand run the TLS-pinning runtime suites plus the out-of-tree consumer's acceptance tests (which terminate real TLS handshakes). It answers "is the next snapshot safe?" before Renovate opens the PR, and stands in for the consumer whose other deps force a newer boringssl than the pin. Its test steps pass--lockfile_mode=offexplicitly: the override makes the checked-in lockfiles stale by construction, and relying on Bazel's current default ofupdatewould break if the default ever flips toerror.osvVulnerabilityAlertsfor the merge-urgency direction ("is it safe not to merge?"), and a repin note on every bazel-module PR mirroring the existingmaven_install.jsonnote.make lockfilesjoinsverify(the Makefile mirrors ci.yml one target per job), theconsumertarget runs the resolution check, anddocs/development.mdlists the new target.Testing
make lockfilespasses locally on both modules after the consumer repin, and error mode was verified to bite: bumping the boringssl pin without a repin fails withMissing checksum … Please run bazel mod deps --lockfile_mode=update../boringssl-resolution-check.shpasses (resolved boringssl@0.20260730.0 matches smithy_cpp's pin).-Wall -Wextraagainst boringssl 0.20260730.0, Boost 1.90, and googletest 1.17 headers;clang-format --dry-run --Werroris clean. The sandbox's egress policy blocks a toolchain archive the fullbazel testneeds, so the two new TLS tests run for the first time in this PR's CI matrix — 7 jobs exercise them: the four-toolchain matrix, both ASan/UBSan legs, and the coverage run. (The TSan step covers only the concurrency suites, which don't includebeast_client_test.)renovate.jsonis valid JSON.Checklist
bazel test //...and(cd codegen && gradle build spotlessCheck)pass locally (sandbox egress blocks one toolchain fetch; validated by this PR's CI instead)🤖 Generated with Claude Code
https://claude.ai/code/session_015oE5zkytVkgzmKNPSP2CWM
Generated by Claude Code